import java.text.DateFormat;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * Content: Timer计时器
 * --------------------------------------------------
 * Java 定时器 Timer 源码分析和使用建议: https://juejin.cn/post/6844903535029534733
 */

public class java_1118_threadPool {
    public static void main(String[] args) {

        // Java线程池
        System.out.println("--------------------Java线程池--------------------");

        try {
            // newCachedThreadPool(): 创建一个 可缓存 线程池。
            System.out.println("-----newCachedThreadPool(): 创建一个 可缓存 线程池-----");
            testMethod1();

            System.out.println("-----newFixedThreadPool(): 创建一个 固定大小 的线程池-----");
            testMethod2();

            System.out.println("-----newScheduledThreadPool(5): 创建一个 定长 的线程池，支持 定时 任务-----");
            testMethod3();

            System.out.println("-----newSingleThreadExecutor(): 创建一个 单线程 的线程池-----");
            testMethod4();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    // newCachedThreadPool(): 创建一个 可缓存 线程池
    public static void testMethod1() throws Exception {

        // 可缓存的线程池
        ExecutorService executor = Executors.newCachedThreadPool();

        for (int i = 0; i < 5; i++) {

            final int index = i;

            Thread.sleep(1000);

            executor.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName() + "  " + index);
                }
            });
        }
    }

    // newFixedThreadPool(): 创建一个 固定大小 的线程池
    public static void testMethod2() throws InterruptedException {

        ExecutorService executor = Executors.newFixedThreadPool(1);

        for (int i = 0; i < 10; i++) {

            Thread.sleep(1000);
            final int index = i;

            executor.execute(() -> {
                try {
                    Thread.sleep(2 * 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "  " + index);
            });
        }
        executor.shutdown();
    }

    // newScheduledThreadPool(5): 创建一个 定长 的线程池，支持 定时 任务
    public static void testMethod3() {
        ScheduledExecutorService executor = Executors.newScheduledThreadPool(5);

        executor.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                // 开始时间
                long start = new Date().getTime();

                System.out.println("scheduleAtFixedRate 开始执行时间:" +
                        DateFormat.getTimeInstance().format(new Date()));
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                // 结束时间
                long end = new Date().getTime();
                System.out.println("scheduleAtFixedRate 执行花费时间=" + (end - start) / 1000 + "m");
                System.out.println("scheduleAtFixedRate 执行完成时间：" + DateFormat.getTimeInstance().format(new Date()));
                System.out.println("======================================");
            }
        }, 1, 5, TimeUnit.SECONDS);
    }

    // newSingleThreadExecutor(): 创建一个 单线程 的线程池
    public static void testMethod4() {

        ExecutorService executor = Executors.newSingleThreadExecutor();

        for (int i = 0; i < 5; i++) {
            final int index = i;
            executor.execute(() -> {
                try {
                    Thread.sleep(2 * 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "   " + index);
            });
        }
        executor.shutdown();
    }
}
